/*
 * Copyright [2012] Gurkan Erdogdu
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.   
*/   
package com.google.code.miniwebserver;

import java.io.File;
import java.io.FileInputStream;

import org.apache.coyote.ActionCode;
import org.apache.coyote.Adapter;
import org.apache.coyote.OutputBuffer;
import org.apache.coyote.Request;
import org.apache.coyote.Response;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.net.SocketStatus;

/**
 * Implementation of the {@link Adapter} that responds
 * file content to the browser.
 * 
 * @author gurkanerdogdu
 *
 */
public class FileAdapter implements Adapter{
    
    /**
     * {@inheritDoc}
     */
    @Override
    public void service(Request req, Response res) throws Exception {
        
        //Which file is requested
        String requestUri = req.requestURI().toString();
        
        //Response Buffer
        OutputBuffer outputBuffer = res.getOutputBuffer();
        
        //Look for the file from file system
        FileInputStream fis = null;
        try{
            File lookFile = new File(Constants.FILE_PROVIDER_LOCATION,requestUri);            
            if(lookFile.exists()){
                fis = new FileInputStream(lookFile);
                
                if(!requestUri.contains(".html")){
                    res.setContentType("application/x-download;charset=utf-8");
                    res.setHeader("Content-Disposition", "attachment; filename=" + requestUri.substring(1));                    
                }
                                
                ByteChunk byteChunk = new ByteChunk(fis.available());
                
                byte[] b = new byte[8192];
                int read = -1;
                while((read = fis.read(b)) != -1){
                    byteChunk.append(b, 0, read);
                }
                
                outputBuffer.doWrite(byteChunk,res);                            
            }else{
                MessageBytes mbytes = MessageBytes.newInstance();
                byte[] temp = "File does not exist".getBytes();
                mbytes.setBytes(temp,0,temp.length);
                
                //Write
                outputBuffer.doWrite(mbytes.getByteChunk(), res);
            }
            
            res.action(ActionCode.COMMIT, null);
            
        }catch(Exception e){
            MessageBytes mbytes = MessageBytes.newInstance();
            byte[] temp = "Exception has been occured to get file".getBytes();
            mbytes.setBytes(temp,0,temp.length);
            
            res.action(ActionCode.COMMIT, null);
        }
        finally{
            //Close stream
            if(fis != null){
                fis.close();
            }
        }
        
        
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean event(Request req, Response res, SocketStatus status) throws Exception {
        return false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean asyncDispatch(Request req, Response res, SocketStatus status) throws Exception {
        return false;
    }

    /**
     * {@inheritDoc}
     */    
    @Override
    public void log(Request req, Response res, long time) {
        
    }

    /**
     * {@inheritDoc}
     */    
    @Override
    public String getDomain() {
        return null;
    }

}
